package Stack;

import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;

/**
 *  题目 ： 计算后缀表达式的结果
 *  题目详述 ：
 *  根据 逆波兰表示法，求该后缀表达式的计算结果。
 *  有效的算符包括 +、-、*、/ 。每个运算对象可以是整数，也可以是另一个逆波兰表达式
 */
public class OfferP36 {

    public int evalRPN(String[] tokens) {
        /**
         *  核心思想 ：
         *  计算后缀表达式结果的实现方法 ：
         * （1）遇到数字的话，直接入栈
         * （2）遇到符号的话，需要从栈中弹出两个数字，在将计算所得到的数字压入栈中
         */
        // 由于符号不需要入栈，只有数字会进入栈中，所以栈中所能存储的数据类型，即为Integer
        Deque<Integer> stack = new LinkedList<>();
        for (String token : tokens) {
            switch (token) {
                // 题目条件 : 有效的算符包括 +、-、*、/  ===> 只需要考虑这四个字符的情况，其他的皆为数字
                case "+" :
                case "-" :
                case "*" :
                case "/" :
                    Integer number1 = stack.pop();
                    Integer number2 = stack.pop();
                    stack.push(Calculate(number1,number2,token));
                    break; // switch中的每一个case都需要break，否则会继续执行下去
                default :
                    // 由于token数组中所存储的数据都是String类型的，而栈中所存储的数据类型为Integer类型
                    // 即，使用Integer.parseInt(String)方法，将字符串转化为Integer类型
                    stack.push(Integer.parseInt(token));
                    break;
            }
        }
        return stack.pop();
    }

    private Integer Calculate(Integer number1, Integer number2,String token) {
        switch (token) {
            // 题目条件 : 有效的算符包括 +、-、*、/  ===> 只需要考虑这四个字符的情况，其他的皆为数字
            case "+" :
                return number2 + number1;
            case "-" :
                return number2 - number1;
            case "*" :
                return number2 * number1;
            case "/" :
                if(number2 == 0){
                    // 若是除法的被除数为0的话，即会报错
                    return 0;
                }
                return number2 / number1;
            default :
                return 0;
        }
    }
}
